package com.casems.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.casems.commons.dto.Menus;
import com.casems.commons.execption.ParamExecption;
import com.casems.commons.util.JwtUtil;
import com.casems.commons.util.ValidatorUtil;
import com.casems.commons.vo.LoginVO;
import com.casems.commons.vo.PageVO;
import com.casems.commons.vo.RegisterVO;
import com.casems.controller.CodeController;
import com.casems.entity.User;
import com.casems.entity.UserRole;
import com.casems.mapper.UserMapper;
import com.casems.mapper.UserRoleMapper;
import com.casems.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tch
 * @since 2023-05-12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    @Override
    public User getUser(String phone) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phone",phone);
        return getOne(queryWrapper);
    }

    @Override
    public String login(LoginVO loginVO) {
        //校验
        ValidatorUtil.validator(loginVO);

        String savedCode = stringRedisTemplate.opsForValue()
                .get(CodeController.CODE_PREFIX + loginVO.getUuid());

        // 校验验证码
        if(StringUtils.isEmpty(savedCode)){
            throw new ParamExecption("验证码过期",400);
        }
        if(!StringUtils.equalsIgnoreCase(savedCode,loginVO.getCode())){
            throw new ParamExecption("验证码错误",400);
        }
        //验证用户名
        User user = this.getUser(loginVO.getPhone());
        if(ObjectUtils.isEmpty(user)){
            throw new ParamExecption("手机号或密码错误!",400);
        }

        String password = SecureUtil.md5(loginVO.getPassword());
        if(!StringUtils.equals(password,user.getPassword())){
            throw new ParamExecption("用户名或密码错误",400);
        }
        return JwtUtil.createToken(user.getPhone());
    }

    @Transactional
    @Override
    public String register(RegisterVO registerVO) {
        //校验
        ValidatorUtil.validator(registerVO);
        String savedSMSCode = stringRedisTemplate.opsForValue()
                .get(registerVO.getPhone());
        // 校验验证码
        if(StringUtils.isEmpty(savedSMSCode)){
            throw new ParamExecption("短信验证码过期",400);
        }
        if(!StringUtils.equalsIgnoreCase(savedSMSCode,registerVO.getSmsCode())){
            throw  new ParamExecption("短信验证码错误",400);
        }
        //验证用户名
        if(this.getUser(registerVO.getPhone())!=null){
            throw new ParamExecption("该手机号已经被使用，请检查后重试",400);
        }
        registerVO.setPassword(SecureUtil.md5(registerVO.getPassword()));
        if(save(registerVO)) {
            userRoleMapper.insert(new UserRole(null,registerVO.getId(),3));
            return JwtUtil.createToken(registerVO.getPhone());
        }
        return null;
    }

    @Override
    public List<Menus> getMenusByUserId(int userId) {
        return userMapper.getMenusByUserId(userId);
    }

    @Override
    public void setChildren(Menus top, List<Menus> menus) {
        List<Menus> children = new ArrayList<>();
        for(Menus child : menus){
            if(child.getPid() == top.getId()){
                children.add(child);
            }
        }
        top.setNodes(children);
        if(children.size()>0){
            children.forEach(item->{
                setChildren(item,menus);
            });
        }
    }

    @Override
    public PageVO<User> getAllStaff(int pageNumber, int pageSize,User user) {
        PageHelper.startPage(pageNumber,pageSize);

        List<User> allStaff = userMapper.getAllStaff(user);
        PageInfo<User> pageInfo = new PageInfo<>(allStaff);

        return new PageVO<User>(pageInfo.getPageNum(),
                pageInfo.getPageSize(),
                allStaff,
                pageInfo.getTotal());
    }
    @Override
    public PageVO<User> getAllPatient(int pageNumber, int pageSize,User user) {
        PageHelper.startPage(pageNumber,pageSize);

        List<User> allStaff = userMapper.getAllPatient(user);
        PageInfo<User> pageInfo = new PageInfo<>(allStaff);

        return new PageVO<User>(pageInfo.getPageNum(),
                pageInfo.getPageSize(),
                allStaff,
                pageInfo.getTotal());
    }
    @Transactional
    @Override
    public boolean addUser(User user,int roleId) {
        int count = userMapper.insert(user);
        count += userRoleMapper.insert(new UserRole(null,user.getId(),roleId));
        return count>1;
    }

    @Override
    public User getUserForCase(User user) {
        return userMapper.getUserForCase(user);
    }

    @Override
    public String loginSms(LoginVO loginVO) {
        //校验
        ValidatorUtil.validator(loginVO);

        String savedSMSCode = stringRedisTemplate.opsForValue()
                .get(loginVO.getPhone());
        // 校验验证码
        if(StringUtils.isEmpty(savedSMSCode)){
            throw new ParamExecption("短信验证码过期",400);
        }
        if(!StringUtils.equalsIgnoreCase(savedSMSCode,loginVO.getSmsCode())){
            throw  new ParamExecption("短信验证码错误",400);
        }
        //验证用户名
        User user = this.getUser(loginVO.getPhone());
        if(ObjectUtils.isEmpty(user)){
            throw new ParamExecption("手机号未注册或不存在!",400);
        }
        return JwtUtil.createToken(user.getPhone());
    }
}
